package com.jlt.ocr.service.impl;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;

import org.opencv.core.Mat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.jlt.baidu.dto.FileOcrModel;
import com.jlt.baidu.utils.ImageProcessSaveUtil;
import com.jlt.baidu.utils.OcrResultHandleUtil;
import com.jlt.baidu.utils.Opencv420Util;
import com.jlt.baidu.utils.OpencvDialteUtil;
import com.jlt.baidu.utils.OpencvLineUtil;
import com.jlt.ocr.service.TesseractService;
import com.jlt.ocr.tesseract.GlobalTessBaseAPI;
import com.jlt.ocr.tesseract.OcrRectangle;
import com.jlt.ocr.tesseract.OcrResult;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class TesseractServiceImpl implements TesseractService {

    @Value("${process.path}")
    String processPath;

    @Autowired
    GlobalTessBaseAPI api;

    @Override
    public List<FileOcrModel> notExcelImageOcr(List<FileOcrModel> models) {
        if (models == null || models.isEmpty()) {
            return models;
        }
        for (FileOcrModel model : models) {
            long startTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            // 1.读取压缩文件
            Mat mat = Opencv420Util.imagerLoad(model.getFileCompareUrl());
            // 1.1 对图片进行去除excel表格内容
            Mat noexcel = OpencvLineUtil.imageDropExcelBusiness(mat.clone());
            Opencv420Util.imageSave(model.getFileCompareUrl(), noexcel);
            // 2.灰度变化
            Mat first = Opencv420Util.imageGray(noexcel.clone());
            // Opencv420Util.imageSave(ImageProcessSaveUtil.processRedUrl(processPath, model.getUuid(), model.getFileType()), first);
            // 3.高斯滤波降噪
            Mat mat1 = Opencv420Util.gaussianBlur(first.clone());
            // 4.边缘检测
            Mat sobel = Opencv420Util.imageCanny(mat1, 120, 200);
            // 5.中值滤波
            Mat mat2 = Opencv420Util.medianBlur(sobel.clone());
            // 6.图片二值化，去除背景，增强图片
            Mat mat3 = Opencv420Util.thresholdWhiteGround(mat2.clone(), 100);
            // 7.腐蚀，膨胀 核心代码
            Mat mat4 = OpencvDialteUtil.commonDialate(mat3.clone());
            // 8.画出轮廓线
            List<OcrRectangle> rangeList = OpencvLineUtil.commonImageLine(noexcel, mat4);
            Opencv420Util.imageSave(ImageProcessSaveUtil.processLineUrl(processPath, model.getUuid(), model.getFileType()), noexcel);
            // 9.文字识别业务
            List<OcrResult> ocrResult = OcrResultHandleUtil.commonImageOcr(api, model.getFileCompareUrl(), rangeList);
            // 10. 填充识别内容
            long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            model.setRequestTime((endTime - startTime) / 1000.0);
            model.setDiscernResult(0);
            model.setSuccessResult(JSONObject.toJSONString(ocrResult));
        }
        return models;
    }

    @Override
    public List<FileOcrModel> excelNotImageOcr(List<FileOcrModel> models) {
        if (models == null || models.isEmpty()) {
            return models;
        }
        for (FileOcrModel model : models) {
            long startTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            // 1.读取压缩文件
            Mat mat = Opencv420Util.imagerLoad(model.getFileCompareUrl());
            // 1.1 对图片进行去除非excel表格内容
            Mat noexcel = OpencvLineUtil.imageDropNotExcelBusiness(mat.clone());
            Opencv420Util.imageSave(model.getFileCompareUrl(), noexcel);
            // 2.灰度
            Mat first = Opencv420Util.imageGray(noexcel.clone());
            // 3.高斯滤波降噪
            Mat mat1 = Opencv420Util.gaussianBlur(first.clone());
            // 4.边缘检测
            Mat sobel = Opencv420Util.imageCanny(mat1.clone(), 120, 200);
            // 5.中值滤波
            Mat mat2 = Opencv420Util.medianBlur(sobel.clone());
            // 6.图片二值化，去除背景，增强图片
            Mat mat3 = Opencv420Util.thresholdWhiteGround(mat2.clone(), 100);
            // 7.腐蚀，膨胀 核心代码
            Mat mat4 = OpencvDialteUtil.excelDialate(mat3.clone());
            Opencv420Util.imageSave(ImageProcessSaveUtil.processDialetUrl(processPath, model.getUuid(), model.getFileType()), mat4);
            // 8.画出轮廓线
            List<OcrRectangle> rangeList = OpencvLineUtil.commonImageLine(noexcel, mat4);
            Opencv420Util.imageSave(ImageProcessSaveUtil.processLineUrl(processPath, model.getUuid(), model.getFileType()), noexcel);
            // 9.文字识别业务
            List<OcrResult> ocrResult = OcrResultHandleUtil.excelImageOcr(api, model.getFileCompareUrl(), rangeList);
            // 10. 填充识别内容
            long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            model.setRequestTime((endTime - startTime) / 1000.0);
            model.setDiscernResult(0);
            model.setSuccessResult(JSONObject.toJSONString(ocrResult));
        }
        return models;
    }

    @Override
    public List<FileOcrModel> commonImageOcr(List<FileOcrModel> models) {
        if (models == null || models.isEmpty()) {
            return models;
        }
        for (FileOcrModel model : models) {
            long startTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            // 1.读取压缩文件
            Mat mat = Opencv420Util.imagerLoad(model.getFileCompareUrl());
            // 2.灰度
            Mat first = Opencv420Util.imageGray(mat.clone());
            // 3.高斯滤波降噪
            Mat mat1 = Opencv420Util.gaussianBlur(first.clone());
            // 4.边缘检测
            Mat sobel = Opencv420Util.imageCanny(mat1, 120, 200);
            // 5.中值滤波
            Mat mat2 = Opencv420Util.medianBlur(sobel.clone());
            // 6.图片二值化，去除背景，增强图片
            Mat mat3 = Opencv420Util.thresholdWhiteGround(mat2.clone(), 100);
            // 7.腐蚀，膨胀 核心代码
            Mat mat4 = OpencvDialteUtil.commonDialate(mat3.clone());
            // 8.画出轮廓线
            List<OcrRectangle> rangeList = OpencvLineUtil.commonImageLine(mat, mat4);
            Opencv420Util.imageSave(ImageProcessSaveUtil.processLineUrl(processPath, model.getUuid(), model.getFileType()), mat);
            // 9.文字识别业务
            List<OcrResult> ocrResult = OcrResultHandleUtil.commonImageOcr(api, model.getFileCompareUrl(), rangeList);
            // 10. 填充识别内容
            long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            model.setRequestTime((endTime - startTime) / 1000.0);
            model.setDiscernResult(0);
            model.setSuccessResult(JSONObject.toJSONString(ocrResult));
        }
        return models;
    }

    @Override
    public List<FileOcrModel> excelImageOcr(List<FileOcrModel> models) {
        if (models == null || models.isEmpty()) {
            return models;
        }
        for (FileOcrModel model : models) {
            long startTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            // 1.读取压缩文件
            Mat mat = Opencv420Util.imagerLoad(model.getFileCompareUrl());
            // 1.1对表格的边缘进行扩展
            Mat extend = Opencv420Util.extendImageBorder(mat.clone(), 0.02);
            Opencv420Util.imageSave(model.getFileCompareUrl(), extend);
            // 2.灰度
            Mat first = Opencv420Util.imageGray(mat.clone());
            // 3.高斯滤波降噪
            Mat mat1 = Opencv420Util.gaussianBlur(first.clone());
            // 4.边缘检测
            Mat sobel = Opencv420Util.imageCanny(mat1.clone(), 120, 200);
            // 5.中值滤波
            Mat mat2 = Opencv420Util.medianBlur(sobel.clone());
            // 6.图片二值化，去除背景，增强图片
            Mat mat3 = Opencv420Util.thresholdWhiteGround(mat2.clone(), 100);
            // 7.腐蚀，膨胀 核心代码
            Mat mat4 = OpencvDialteUtil.excelDialate(mat3.clone());
            Opencv420Util.imageSave(ImageProcessSaveUtil.processDialetUrl(processPath, model.getUuid(), model.getFileType()), mat4);
            // 8.画出轮廓线
            List<OcrRectangle> rangeList = OpencvLineUtil.commonImageLine(extend, mat4);
            Opencv420Util.imageSave(ImageProcessSaveUtil.processLineUrl(processPath, model.getUuid(), model.getFileType()), extend);
            // 9.文字识别业务
            List<OcrResult> ocrResult = OcrResultHandleUtil.excelImageOcr(api, model.getFileCompareUrl(), rangeList);
            // 10. 填充识别内容
            long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            model.setRequestTime((endTime - startTime) / 1000.0);
            model.setDiscernResult(0);
            model.setSuccessResult(JSONObject.toJSONString(ocrResult));
        }
        return models;
    }

}
